/**
 * And is a subclass of the class Gate.
 * It has four fields: 
 * left is the x value respect the left top angle of the GUI, 
 * top is the y value respect the left top angle of the GUI,
 * width is the width of the and gate visual object, and
 * height is its height.
 * 
 *  @author Giuseppe Mendola (giuseppe.mendola@usi.ch);Gregory Banfi (gregory.banfi@usi.ch);
 *  @version 24.05.2011
 */

package ch.usi.inf.pf2.Gates;

import java.awt.Color;
import java.awt.Graphics;
import java.io.Serializable;
import java.util.ArrayList;

import ch.usi.inf.pf2.Component;
import ch.usi.inf.pf2.Value;
import ch.usi.inf.pf2.pins.InputPin;
import ch.usi.inf.pf2.pins.OutputPin;
import ch.usi.inf.pf2.pins.Pin;

public class And extends Gate implements Component, Serializable {

	/**
	 * Fields for the GUI
	 */
	// private ArrayList<InputPin> inputPins = new ArrayList<InputPin>();
	private int left;
	private int top;
	private int width;
	private int height;
	private static int time1;
	private static int time2;

	/**
	 * This is the constructor of the And class. It passes the arguments to the
	 * constructor of its superclass Gates.
	 */
	public And(final ArrayList<InputPin> inputPins, final OutputPin outputPin,
			final int x, final int y) {
		super(inputPins, outputPin);
		this.time1 = 200;
		this.time2 = 200;
		OutputPin o1 = new OutputPin(Value.UNKNOWN);
		this.outputPin = o1;
		InputPin i1 = new InputPin(Value.UNKNOWN);
		InputPin i2 = new InputPin(Value.UNKNOWN);
		this.inputPins.add(i1);
		this.inputPins.add(i2);

		// Constructor for the GUI
		this.left = x;
		this.top = y;
		width = 20;
		height = 40;
	}

	public void setInputPinValue(int x, Value value) {
		inputPins.get(x).setValue(value);
	}

	/**
	 * This method compute the behavior of an and logical operator. It takes an
	 * ArrayList of inputPin as argument, it gets the value enum out of the
	 * inputPin object and then uses this value to compute the and operator.
	 * 
	 * @param inputPins
	 *            An ArrayList of inputPin objects
	 * @return Value A value between true, false and unknown.
	 */
	@Override
	public OutputPin compute(ArrayList<InputPin> inputPins) {
		if (inputPins.size() > 1) {
			outputPin.setValue(Value.TRUE);
			for (final Pin inputPin : inputPins) {
				final Value value = inputPin.getValue();
				if (value == Value.UNKNOWN) {
					outputPin.setValue(Value.UNKNOWN);
					return outputPin;
				} else if (value == Value.FALSE) {
					outputPin.setValue(Value.FALSE);
				}
			}
			return outputPin;
		} else {
			outputPin.setValue(Value.UNKNOWN);
			return outputPin;
		}
	}

	/**
	 * Methods for the GUI
	 */

	@Override
	public void draw(Graphics g, Color color) {
		
		System.out.println("I'm using and.draw()");
		g.setColor(color);
		if (outputPin.getValue() == Value.TRUE) {
			g.setColor(Color.GREEN);
		} else if (outputPin.getValue() == Value.FALSE) {
			g.setColor(Color.RED);
		}
		g.fillRect(left, top, width, height);
		g.fillOval(left, top - 1, width + 15, height + 1);
		g.drawLine(left + width + 15, top + height / 2, left + width + 20, top
				+ height / 2);
		g.drawLine(left - 5, top + 15, left, top + 15);
		g.drawLine(left - 5, top + 25, left, top + 25);
		g.setColor(Color.WHITE);
		g.fillOval(left + 1, top, width + 13, height - 1);
		g.fillRect(left + 1, top + 1, width - 2, height - 2);
	}

	/**
	 * Override methods
	 */
	@Override
	public void add(Component component) {
		// TODO Auto-generated method stub
	}

	@Override
	public void remove(Component component) {
		// TODO Auto-generated method stub
	}

	@Override
	public boolean contains(int x, int y) {
		return x >= left && x <= left + width + 16 && y >= top
				&& y <= top + height + 3;
	}

	@Override
	public int getOriginX() {
		return left;
	}

	@Override
	public int getOriginY() {
		// TODO Auto-generated method stub
		return top;
	}

	@Override
	public Value getValue() {
		return outputPin.getValue();
	}

	@Override
	public void setValue(Value value) {
		// TODO Auto-generated method stub
	}

	@Override
	public void setOutputPin(OutputPin outputPin) {
		// TODO Auto-generated method stub

	}

	private int firstPin = 0;

	@Override
	public int getFirstFreePin() {

		if (firstPin < 2) // getInputPins().size())
			firstPin++;

		return firstPin;
	}

	@Override
	public boolean hasFreePins() {
		// TODO Auto-generated method stub
		return (firstPin < 2); // getInputPins().size());
	}

	@Override
	public void setOrigin(int x, int y) {
		this.left = x;
		this.top = y;
	}

	@Override
	public OutputPin getOutputPin() {
		return outputPin;
	}

	@Override
	public InputPin getInputPin() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void setOutputValue() {
		// TODO Auto-generated method stub
	}

}
